﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

namespace AutoProbe
{
    public class ProbeInfos
    {
        public string GetHostingInfos()
        {
            var doc = new XmlDocument();

            var xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            var rootNode = doc.CreateElement("HostingInfos");
            rootNode.SetAttribute("version", "1");
            doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
            doc.AppendChild(rootNode);

            var server = doc.CreateElement("Server");
            server.SetAttribute("name",
                                ConfigurationManager.AppSettings["ProbeServerName"] ??
                                Dns.GetHostByName(Dns.GetHostName()).HostName);
            server.SetAttribute("ipAddress", HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"]);
            rootNode.AppendChild(server);

            var webSite = doc.CreateElement("Website");
            var mapPath = HttpContext.Current.Server.MapPath("/");
            webSite.SetAttribute("name",
                                 ConfigurationManager.AppSettings["ProbeWebSiteBaseURL"] ?? GetWebSiteNameFromMapPath());
            webSite.SetAttribute("rootPath", mapPath);
            webSite.SetAttribute("technologyName", ".NET");
            server.AppendChild(webSite);

            var assemblies = doc.CreateElement("Assemblies");
            webSite.AppendChild(assemblies);

            var medianamikVersion = "N/A";
            var technologyVersion = "N/A";

            var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var asm in loadedAssemblies)
            {
                var assembly = doc.CreateElement("Assembly");
                assembly.SetAttribute("name", asm.GetName().Name);
                assembly.SetAttribute("version", asm.GetName().Version.ToString());

                if (Regex.IsMatch(asm.GetName().Name, @"^Medianamik\w{0,3}$", RegexOptions.IgnoreCase))
                    medianamikVersion = asm.GetName().Version.ToString();

                if (Regex.IsMatch(asm.GetName().Name, @"^Medianamik.Core$", RegexOptions.IgnoreCase))
                    medianamikVersion = asm.GetName().Version.ToString();

                if (asm.GetName().Name.Equals("System", StringComparison.OrdinalIgnoreCase) &&
                    medianamikVersion == "N/A")
                    technologyVersion = asm.GetName().Version.ToString();


                if (asm.GetName().Name.Equals("System.Core", StringComparison.OrdinalIgnoreCase))
                    technologyVersion = asm.GetName().Version.ToString();


                try
                {
                    assembly.SetAttribute("fileVersion", FileVersionInfo.GetVersionInfo(asm.Location ?? "").FileVersion);
                }
                catch (Exception e)
                {
                }
                assemblies.AppendChild(assembly);
            }

            webSite.SetAttribute("technologyVersion", technologyVersion);

            var cs = GetCS();
            var sqlTools = new SQLTools(cs);

            var medianamik = doc.CreateElement("Medianamik");
            medianamik.SetAttribute("version", medianamikVersion);
            medianamik.SetAttribute("lastInstalledPatch",
                                    medianamikVersion.StartsWith("2.") ? sqlTools.GetMedianamikLatestPatch() : "");
            //medianamik.SetAttribute("cs", cs);
            webSite.AppendChild(medianamik);

            var database = doc.CreateElement("Database");
            database.SetAttribute("name", sqlTools.GetSQLServerName() ?? GetCSSection(cs, "Database"));
            database.SetAttribute("version", sqlTools.GetSQLServerVersion());
            database.SetAttribute("ipAddress", GetCSSection(cs, "Server"));
            webSite.AppendChild(database);

            var coveo = doc.CreateElement("Coveo");
            coveo.SetAttribute("version", "");
            webSite.AppendChild(coveo);

            var dns = doc.CreateElement("Dns");
            dns.SetAttribute("primary", "");
            dns.SetAttribute("secondary", "");
            webSite.AppendChild(dns);

            return doc.OuterXml;
        }

        private string GetWebSiteNameFromMapPath()
        {
            var mapPath = HttpContext.Current.Server.MapPath("/");
            mapPath = mapPath.TrimEnd('\\');

            if (mapPath.IndexOf('\\') > 0)
            {
                mapPath = mapPath.Substring(mapPath.LastIndexOf('\\'));
                mapPath = mapPath.TrimStart('\\');
            }

            return mapPath;
        }

        private string GetCS()
        {
#if NET_1_1
            return ConfigurationSettings.AppSettings["CS"] ?? "";
#else
            return ConfigurationManager.AppSettings["CS"] ??
                   (ConfigurationManager.ConnectionStrings["CS"] == null
                        ? ""
                        : ConfigurationManager.ConnectionStrings["CS"].ConnectionString ?? "");
#endif
        }

        private string GetCSSection(string cs, string searchedPart)
        {
            Array csSections = cs.Split(';');

            foreach (string part in csSections)
                if (part.Trim().StartsWith(searchedPart, StringComparison.OrdinalIgnoreCase))
                    if (part.Contains("="))
                        return part.Split('=')[1].Trim();

            return "";
        }
    }
}